package com.atguigu.spzx.manager.service.Impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.manager.mapper.SysUserMapper;
import com.atguigu.spzx.manager.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.dto.system.SysUserDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.model.vo.system.LoginVo;
import com.atguigu.spzx.service.exception.GuliException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: SysUserServiceImpl
 * Package: com.atguigu.spzx.manager.service.Impl
 * Description:
 *
 * @Author 刘强
 * @Create 2024/6/29 11:39
 * @Version 1.0
 */
@Service
public class SysUserServiceImpl implements SysUserService {
    @Resource
    private SysUserMapper sysUserMapper;
    //    @Resource
//    private RedisTemplate<String ,String > redisTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public LoginVo login(LoginDto loginDto) {
        // 0. 验证码校验
        String codeKey = loginDto.getCodeKey();
        // 获取用户输入的验证码
        String captchaInput = loginDto.getCaptcha();
        String captchaRedis = stringRedisTemplate.opsForValue().get("user:login:validateCode:" + codeKey);
        if (StrUtil.isEmpty(captchaRedis) || StrUtil.isEmpty(captchaInput) || !StrUtil.equalsIgnoreCase(captchaInput, captchaRedis)) {
            throw new GuliException(201, "验证码错误");
        }
        // 1. 根据用户名获取用户信息 （从数据库）
        String userName = loginDto.getUserName();
        SysUser sysUser = sysUserMapper.selectByUsername(userName);
        // 2. 对明文密码进行加密
        if (sysUser == null) {
            throw new GuliException(201, "用户名不存在");
        }
        String password = loginDto.getPassword();
        if (StringUtils.isEmpty(password)) {
            throw new GuliException(201, "密码不能为空");
        }
        String passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes());
        // 3. 校验密码是否正确
        if (!passwordMd5.equals(sysUser.getPassword())) {
            throw new GuliException(201, "密码错误");
        }
        // 4. 生成token  --> 这里我们使用uuid+redis来实现token功能
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        // 5. 将token保存在redis中，并且设置过期时间
        stringRedisTemplate.opsForValue().set("user:login:" + token, JSON.toJSONString(sysUser), 30, TimeUnit.MINUTES);
        // 6. 响应结果LoginVo的封装
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        // 7. 登陆成功后删除 redis中的验证码
        stringRedisTemplate.delete("user:login:validateCode:" + codeKey);
        return loginVo;
    }

    @Override
    public SysUser getUserInfo(String token) {
        String userStr = stringRedisTemplate.opsForValue().get("user:login:" + token);
        if (userStr == null) {
            throw new GuliException(201, "token已过期");
        }
        return JSON.parseObject(userStr, SysUser.class);
    }

    @Override
    public void logout(String token) {
        stringRedisTemplate.delete("user:login:" + token);
    }

    @Override
    public PageInfo<SysUser> findByPage(SysUserDto sysUserDto, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<SysUser> list = sysUserMapper.findByPage(sysUserDto, pageNum, pageSize);
        return new PageInfo<SysUser>(list);
    }

    @Override
    public void saveSysUser(SysUser sysUser) {
        SysUser sysUserRegistered = sysUserMapper.selectByPhone(sysUser.getPhone());
        if (sysUserRegistered != null) {
            throw new GuliException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        sysUser.setStatus(0);
        sysUser.setPassword(DigestUtils.md5DigestAsHex(sysUser.getPassword().getBytes()));
        if (StrUtil.isEmpty(sysUser.getAvatar())) {
            sysUser.setAvatar("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
        }
        sysUserMapper.saveSysUser(sysUser);
    }

    /**
     * 修改用户信息
     *
     * @param sysUser
     */
    @Override
    public void updateSysUser(SysUser sysUser) {
        String phone = sysUser.getPhone();
        SysUser sysUserExists = sysUserMapper.selectByPhone(phone);

        if (sysUserExists != null) {

            // 如果手机号码本身就是自己的(没有进行修改)，则不进行修改
            if (sysUserExists.getId() == sysUser.getId()) {
                sysUser.setPhone(null);
            } else {
                throw new GuliException(201, "该手机号码已经存在!");
            }
        }
        String password = sysUser.getPassword();
        if (!StrUtil.isEmpty(password)) {
            sysUser.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        }

        sysUserMapper.updateSysUser(sysUser);
    }

    /**
     * 根据id删除用户
     * @param sysUserId
     */
    @Override
    public void deleteById(Long sysUserId) {
        sysUserMapper.deleteById(sysUserId);
    }
}
